package com.barryredmond.mileagecalc;

import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;

public class SettingsForm extends Form implements CommandListener, ItemStateListener{

    protected static final String USE_IMPERIAL = "use-imperail";
    protected static final String SHOW_KILOMETERS = "show-kilometers";
    protected static final String SHOW_MILES = "show-miles";
    protected static final String SHOW_LITRES = "show-litres";
    protected static final String SHOW_GALLONS = "show-gallons";
    protected static final String SHOW_LITRES_PER_100_KILOMETERS = "show-litres-per-100-kilometers";
    protected static final String SHOW_KILOMETERS_PER_LITRE = "show-kilometers-per-litre";
    protected static final String SHOW_MILES_PER_GALLON = "show-miles-per-gallon";
    
    private static final Settings settings = Settings.getSettings();
    
    private final int IMPERIAL = 0;
    private final int US = 1;
    
    private final int KILOMETERS = 0;
    private final int MILES = 1;
    private final int LITRES = 2;
    private final int GALLONS = 3;

    private final int LITRES_PER_100_KILOMETERS = 0;
    private final int KILOMETERS_PER_LITRE = 1;
    private final int MILES_PER_GALLON = 2;
    
    private MileageForm previous;
    
    private final Command backCommand;
    
    private final ChoiceGroup imperialOrUsGallons;
    private final ChoiceGroup inputsToDisplay;
    private final ChoiceGroup outputsToDisplay;
    private final boolean[] lastInputState;
    private final boolean[] lastOutputsState;
    
    public SettingsForm(MileageForm previous) {
        super("Settings");
        this.previous = previous;
        
        this.addCommand(backCommand = new Command("Back", Command.BACK, 1));
        this.setCommandListener(this);
        
        this.imperialOrUsGallons = new ChoiceGroup("Imperial or US Gallons", Choice.EXCLUSIVE, new String[] {"Imperial", "US"}, null);
        this.imperialOrUsGallons.setSelectedIndex(settings.getBoolean(USE_IMPERIAL, true)?IMPERIAL:US, true);
        this.append(this.imperialOrUsGallons);
        
        this.inputsToDisplay = new ChoiceGroup("Show (Inputs):", Choice.MULTIPLE, new String[] {"Kilometers", "Miles", "Litres", "Gallons"}, null);
        this.inputsToDisplay .setSelectedIndex(KILOMETERS, settings.getBoolean(SHOW_KILOMETERS, true));
        this.inputsToDisplay .setSelectedIndex(MILES, settings.getBoolean(SHOW_MILES, true));
        this.inputsToDisplay .setSelectedIndex(LITRES, settings.getBoolean(SHOW_LITRES, true));
        this.inputsToDisplay .setSelectedIndex(GALLONS, settings.getBoolean(SHOW_GALLONS, true));
        this.append(this.inputsToDisplay);
        this.lastInputState = new boolean[4];
        this.inputsToDisplay.getSelectedFlags(lastInputState);
        
        this.outputsToDisplay = new ChoiceGroup("Show (Output):", Choice.MULTIPLE, new String[] {"Litres/100Km", "Km/Litre", "Miles/Gallon"}, null);
        this.outputsToDisplay .setSelectedIndex(LITRES_PER_100_KILOMETERS, settings.getBoolean(SHOW_LITRES_PER_100_KILOMETERS, true));
        this.outputsToDisplay .setSelectedIndex(KILOMETERS_PER_LITRE, settings.getBoolean(SHOW_KILOMETERS_PER_LITRE, true));
        this.outputsToDisplay .setSelectedIndex(MILES_PER_GALLON, settings.getBoolean(SHOW_MILES_PER_GALLON, true));
        this.append(this.outputsToDisplay);
        this.lastOutputsState = new boolean[4];
        this.outputsToDisplay.getSelectedFlags(lastOutputsState);
        
        this.setItemStateListener(this);
    }

    public void commandAction(Command command, Displayable disp) {
        if(disp == this){
            if(command == backCommand){
                saveState();                
                previous.refresh();
                Display.getDisplay(MileageMIDlet.getMileageMIDlet()).setCurrent(previous);
            }
        }
    }

    public void itemStateChanged(Item item) {
        if(item == this.inputsToDisplay){
        	/*
        	 * The list of what inputs should be displayed has been changed.<br/>
        	 * We now should make sure that at least one of <MILES/KILOMETERS> and one of <GALLONS/LITRES> are each displayed.
        	 */
            final boolean[] showItemsState = new boolean[4];
            this.inputsToDisplay.getSelectedFlags(showItemsState);
            
            if(!showItemsState[KILOMETERS] && !showItemsState[MILES]){
                if(this.lastInputState[KILOMETERS]){
                    this.inputsToDisplay.setSelectedIndex(MILES, true);
                }else{
                    this.inputsToDisplay.setSelectedIndex(KILOMETERS, true);
                }
            }
            if(!showItemsState[LITRES] && !showItemsState[GALLONS]){
                if(this.lastInputState[LITRES]){
                    this.inputsToDisplay.setSelectedIndex(GALLONS, true);
                }else{
                    this.inputsToDisplay.setSelectedIndex(LITRES, true);
                }
            }
            
            this.inputsToDisplay.getSelectedFlags(this.lastInputState);
        }else if(item == this.outputsToDisplay){
        	/*
        	 * The list of what OUTPUTS should be displayed had been changed.<br/>
        	 * We now should make sure that AT LEAST ONE of them will be displayed.
        	 */
            final boolean[] showItemsState = new boolean[4];
            this.outputsToDisplay.getSelectedFlags(showItemsState);
            
        	if(!showItemsState[LITRES_PER_100_KILOMETERS] && !showItemsState[KILOMETERS_PER_LITRE] && !showItemsState[MILES_PER_GALLON]){
        		if(this.lastOutputsState[LITRES_PER_100_KILOMETERS]){
        			this.outputsToDisplay.setSelectedIndex(KILOMETERS_PER_LITRE, true);
        		}else if(this.lastOutputsState[KILOMETERS_PER_LITRE]){
        			this.outputsToDisplay.setSelectedIndex(MILES_PER_GALLON, true);
        		}else{
        			this.outputsToDisplay.setSelectedIndex(LITRES_PER_100_KILOMETERS, true);
        		}
        	}
        	
        	this.outputsToDisplay.getSelectedFlags(this.lastOutputsState);
        }
    }
    
    private void saveState(){
        final boolean useImperial = this.imperialOrUsGallons.getSelectedIndex() == IMPERIAL;
        System.out.println(useImperial?"Use Imperial":"Don't use imperial");
        
        final boolean[] inputsState = new boolean[4];
        this.inputsToDisplay.getSelectedFlags(inputsState);
        
        final boolean[] outputsState = new boolean[3];
        this.outputsToDisplay.getSelectedFlags(outputsState);
        
        System.out.println((inputsState[KILOMETERS]?"":"Don't ") + "Show Kilometers");
        System.out.println((inputsState[MILES]?"":"Don't ") + "Show Miles");
        System.out.println((inputsState[LITRES]?"":"Don't ") + "Show Litres");
        System.out.println((inputsState[GALLONS]?"":"Don't ") + "Show Gallons");
        
        settings.setBooleans(new String[]{USE_IMPERIAL, SHOW_KILOMETERS, SHOW_MILES, SHOW_LITRES, SHOW_GALLONS, SHOW_LITRES_PER_100_KILOMETERS, SHOW_KILOMETERS_PER_LITRE, SHOW_MILES_PER_GALLON}, new boolean[] {useImperial, inputsState[0], inputsState[1], inputsState[2], inputsState[3], outputsState[0], outputsState[1], outputsState[2]});
    }


}
